package com.alibaba.boot.netty.groupChat;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.function.BiFunction;

public class GroupChatServer  {

    private Selector selector;


    private ServerSocketChannel listenChannel;


    private static final  int PORT =6667;

    public GroupChatServer(){
        try {
            selector = Selector.open();
            listenChannel = ServerSocketChannel.open();
            listenChannel.socket().bind(new InetSocketAddress(PORT));
            listenChannel.configureBlocking(false);
            listenChannel.register(selector, SelectionKey.OP_ACCEPT);
            listen();
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    private String  readData(SelectionKey key){

        SocketChannel socketChannel = null;
        try {
            socketChannel = (SocketChannel) key.channel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            int count = socketChannel.read(buffer);
            if (count > 0){
                String msg = new String(buffer.array());
                System.out.println("from client:"+msg.trim());
                return msg;
            }
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
        return null;
    }

    public void  sendToAnotherClients(String msg,SocketChannel self){

        System.out.println("tranforming");


        for(SelectionKey key : selector.keys()){

            Channel tChannel = key.channel();

            if (tChannel instanceof  SocketChannel && tChannel!=self){
                SocketChannel dest = (SocketChannel) tChannel;

                ByteBuffer buffer =ByteBuffer.wrap(msg.getBytes());

                try {
                    dest.write(buffer);
                }catch (IOException e){
                    e.printStackTrace();
                   try {
                       System.out.println(dest.getRemoteAddress()+"offline");
                       key.cancel();
                       dest.close();
                   }catch (Exception e1){
                       e1.printStackTrace();
                   }

                }
            }
        }
    }

    public void  listen(){
        try {
            while (true){
                int count = selector.select(2300);
                if (count > 0){

                    Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                    while (iterator.hasNext()) {
                        SelectionKey key = iterator.next();
                        if (key.isAcceptable()) {
                            SocketChannel socketChannel = listenChannel.accept();
                            socketChannel.configureBlocking(false);
                            socketChannel.register(selector, SelectionKey.OP_READ);

                            System.out.println(socketChannel.getRemoteAddress() + "is online");

                        } else if (key.isReadable()) {
                          String msg =  readData(key);
                           sendToAnotherClients(msg, (SocketChannel) key.channel());
                        }
                    }
                    iterator.remove();

                }else {
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        GroupChatServer groupChatServer = new GroupChatServer();
    }
}
